﻿using System;
using System.Collections.Generic;
using System.Linq;

namespace IssueIT.Core.Domain.Model
{
	public class Post : IEntity
	{
		public static readonly Post Empty = new EmptyPost();

		private class EmptyPost : Post
		{
			//TODO: special case impelemtation - set default/statr value for every status element
		}

		private Post _previousPost;

		public static Post NewPost(NewPostCommand command)
		{
			Post post = new Post();
			post.Id = Guid.NewGuid();

			post.CreatedBy = command.PostedBy;

			post.Title = command.Title;
			post.CreatedAt = SystemTime.Now;
			post.Comment = new Comment(command.Text, command.VisibleTo);

			post._previousPost = command.PreviousPost;

			return post;
		}

		public static Post NewPost(User poster)
		{
			Post post = new Post();
			post.Id = Guid.NewGuid();
			post.CreatedBy = poster;

			return post;
		}

		public Post()
		{
			CreatedAt = SystemTime.Now;
		}

		public Guid Id { get; set; }
		public string Title { get; private set; }
		public Comment Comment { get; private set; }
		public User CreatedBy { get; private set; }
		public DateTime CreatedAt { get; private set; }
        public Status Status { get; private set; }

		public bool IsVisibleTo(User displayTo)
		{
			return Comment.IsVisibleTo(displayTo) || CreatedBy.Equals(displayTo) || Updates.Any();
		}

		public string Text(User displayTo)
		{
			if( Comment.IsVisibleTo(displayTo) || CreatedBy.Equals(displayTo) )
			{
				return Comment.Text;
			}

			return string.Empty;
		}


        public IEnumerable<PostUpdate> Updates
        {
            get
	        {
                //TODO: sæt antal på listen
                var list = new List<PostUpdate>();

                if (_previousPost != null)
                {
                    list.AddIfHasChanged("State", _previousPost.Status.State, Status.State);
                    list.AddIfHasChanged("AssignedTo", _previousPost.Status.AssignedTo, Status.AssignedTo);
                    list.AddIfHasChanged("Milestone", _previousPost.Status.PointInTime, Status.PointInTime);
                    list.AddIfHasChanged("Priority", _previousPost.Status.Priority, Status.Priority);
                    list.AddIfHasChanged("Severity", _previousPost.Status.Severity, Status.Severity);

                    if(_previousPost != Post.Empty)
                    {
                        list.AddIfHasChanged("Title", _previousPost.Title, Title);    
                    }
                }

                return list;
            }
        }

	}

    public static class ListExtensions
    {
        public static void AddIfHasChanged(this IList<PostUpdate> list, string atteributeName, object oldValue, object newValue /*, IList<PostUpdate> updateList*/)
        {
            if (oldValue != newValue)
            {
                list.Add(new PostUpdate(atteributeName, oldValue, newValue));
            }
        }
    }
}